<!DOCTYPE html>
<html lang="zh-Hant">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>三維量化分析1.0</title>
  <script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>
  <style>
    :root {
      --primary-color: #1a2b3c;
      --secondary-color: #2a3b4c;
      --red-color: #e74c3c;
      --blue-color: #3498db;
      --highlight-color: #f39c12;
      --text-color: #ecf0f1;
      --border-color: #4a5b6c;
      --profit-positive: #2ecc71;
      --profit-negative: #e74c3c;
      --yang-color: #3498db;
      --yin-color: #e74c3c;
      --grid-bg-color: #2a3b4c;
      --table-bg: #2c3e50;
      --mode-bg: #2d3e50;
      --trend-positive: #2ecc71;
      --trend-negative: #e74c3c;
      --simulation-bg: rgba(243, 156, 18, 0.2);
    }
    
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    body {
      background-color: var(--primary-color);
      color: var(--text-color);
      font-family: 'Segoe UI', 'Microsoft JhengHei', sans-serif;
      padding: 10px;
      display: flex;
      flex-direction: column;
      align-items: center;
      min-height: 100vh;
    }
    
    /* 登录页面样式 */
    .login-container {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: var(--primary-color);
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      z-index: 10000;
      padding: 20px;
    }
    
    .login-box {
      background-color: var(--secondary-color);
      border-radius: 10px;
      padding: 30px;
      width: 100%;
      max-width: 400px;
      box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
      border: 1px solid var(--border-color);
      text-align: center;
    }
    
    .login-title {
      color: var(--highlight-color);
      font-size: 24px;
      margin-bottom: 20px;
      font-weight: bold;
    }
    
    .login-input {
      width: 100%;
      padding: 12px 15px;
      margin-bottom: 15px;
      border-radius: 6px;
      border: 1px solid var(--border-color);
      background-color: rgba(255, 255, 255, 0.1);
      color: var(--text-color);
      font-size: 16px;
      text-align: center;
      letter-spacing: 2px;
    }
    
    .login-input:focus {
      outline: none;
      border-color: var(--highlight-color);
    }
    
    .login-btn {
      width: 100%;
      padding: 12px 15px;
      background: var(--highlight-color);
      color: white;
      border: none;
      border-radius: 6px;
      font-size: 16px;
      font-weight: 600;
      cursor: pointer;
      margin-bottom: 15px;
    }
    
    .login-btn:hover {
      background: #e67e22;
    }
    
    .login-message {
      padding: 10px;
      border-radius: 6px;
      margin-top: 10px;
      text-align: center;
      font-weight: 600;
      display: none;
    }
    
    .login-success {
      background-color: rgba(46, 204, 113, 0.2);
      color: var(--profit-positive);
    }
    
    .login-error {
      background-color: rgba(231, 76, 60, 0.2);
      color: var(--profit-negative);
    }
    
    .contact-info {
      margin-top: 20px;
      color: #bdc3c7;
      font-size: 14px;
      text-align: center;
    }
    
    .countdown-container {
      margin-top: 15px;
      padding: 10px;
      background-color: rgba(52, 152, 219, 0.1);
      border-radius: 6px;
      font-size: 14px;
      color: var(--blue-color);
      display: none;
    }
    
    .countdown-text {
      font-weight: bold;
      font-size: 16px;
    }
    
    /* 主系统容器 - 默认隐藏 */
    .main-system {
      display: none;
      width: 100%;
    }
    
    .header {
      text-align: center;
      margin-bottom: 10px;
      width: 100%;
      position: relative;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 5px;
    }
    
    .header h1 {
      color: var(--highlight-color);
      margin: 5px 0;
      font-size: 18px;
      order: 1;
    }
    
    .header-controls {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 5px;
      order: 2;
    }
    
    .countdown-display {
      background-color: rgba(243, 156, 18, 0.2);
      padding: 5px 10px;
      border-radius: 15px;
      font-size: 12px;
      color: var(--highlight-color);
    }
    
    .logout-btn {
      background: var(--border-color);
      color: white;
      border: none;
      padding: 5px 10px;
      border-radius: 4px;
      cursor: pointer;
      font-size: 11px;
    }
    
    .logout-btn:hover {
      background: #5a6b7c;
    }
    
    .modules-container {
      width: 100%;
      max-width: 600px;
      display: flex;
      flex-direction: column;
      gap: 15px;
      margin-bottom: 15px;
    }
    
    .module {
      background-color: var(--secondary-color);
      border-radius: 8px;
      padding: 10px;
      border: 1px solid var(--border-color);
    }
    
    .module-title {
      text-align: center;
      font-size: 14px;
      color: var(--highlight-color);
      margin-bottom: 8px;
      font-weight: bold;
    }
    
    .board-container {
      width: 100%;
      margin-bottom: 10px;
    }
    
    .board {
      display: grid;
      grid-template-columns: repeat(6, 1fr);
      grid-template-rows: repeat(3, 30px);
      gap: 1px;
      background-color: var(--border-color);
      padding: 2px;
      border-radius: 6px;
      margin-bottom: 8px;
    }
    
    .cell {
      background-color: var(--primary-color);
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 4px;
    }
    
    .circle {
      width: 20px;
      height: 20px;
      border-radius: 50%;
    }
    
    .red { background-color: var(--red-color); }
    .blue { background-color: var(--blue-color); }
    
    .buttons-container {
      display: flex;
      flex-direction: column;
      gap: 8px;
    }
    
    .btn-group {
      display: flex;
      gap: 8px;
    }
    
    .btn {
      padding: 12px 15px;
      font-size: 16px;
      font-weight: 600;
      border: none;
      cursor: pointer;
      border-radius: 6px;
      flex: 1;
    }
    
    .btn-blue { 
      background: var(--blue-color);
      color: white; 
    }
    
    .btn-red { 
      background: var(--red-color);
      color: white; 
    }
    
    .btn-reset {
      background: var(--border-color);
      color: white;
      font-size: 12px;
      padding: 8px 10px;
    }
    
    .btn-back {
      background: var(--border-color);
      color: white;
      font-size: 12px;
      padding: 8px 10px;
    }
    
    .prediction-table-container {
      width: 100%;
      max-width: 600px;
      margin-bottom: 15px;
      background: var(--table-bg);
      border-radius: 8px;
      padding: 10px;
      border: 1px solid var(--border-color);
    }
    
    .card-title {
      text-align: center;
      font-size: 16px;
      color: var(--highlight-color);
      margin-bottom: 8px;
      font-weight: bold;
      font-family: 'Segoe UI', 'Microsoft JhengHei', sans-serif;
    }
    
    .prediction-table {
      width: 100%;
      border-collapse: collapse;
      margin-top: 8px;
      font-size: 12px;
    }
    
    .prediction-table th,
    .prediction-table td {
      padding: 4px 2px;
      text-align: center;
      border: none;
      vertical-align: top;
      width: 25%;
    }
    
    .prediction-table th {
      background-color: var(--primary-color);
      font-weight: 600;
      padding: 6px 2px;
      font-family: 'Segoe UI', 'Microsoft JhengHei', sans-serif;
    }
    
    .prediction-table tr:nth-child(even) {
      background-color: rgba(255, 255, 255, 0.05);
    }
    
    .trend-positive {
      background-color: rgba(46, 204, 113, 0.2);
      color: var(--trend-positive);
      font-weight: bold;
    }
    
    .trend-negative {
      background-color: rgba(231, 76, 60, 0.2);
      color: var(--trend-negative);
      font-weight: bold;
    }
    
    .scroll-tip {
      color: #bdc3c7;
      font-size: 10px;
      text-align: center;
      margin-top: 5px;
      font-style: italic;
    }
    
    .overlay {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background: white;
      color: black;
      border-radius: 6px;
      padding: 12px 20px;
      font-size: 12px;
      font-weight: 600;
      display: none;
      z-index: 1000;
      text-align: center;
    }
    
    .warning-text {
      color: #f39c12;
      font-size: 11px;
      text-align: center;
      margin-top: 8px;
    }
    
    .simulation-row {
      background-color: var(--simulation-bg);
    }
    
    .ask-road-container {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 8px;
      margin-top: 15px;
    }
    
    .ask-road-title {
      text-align: center;
      font-size: 14px;
      color: var(--highlight-color);
      margin-bottom: 8px;
      grid-column: 1 / -1;
    }
    
    .ask-road-btn {
      padding: 10px 5px;
      font-size: 14px;
      font-weight: 600;
      border: none;
      cursor: pointer;
      border-radius: 5px;
      text-align: center;
      background: var(--border-color);
      color: white;
    }
    
    .ask-road-btn:disabled {
      opacity: 0.6;
      cursor: not-allowed;
    }
    
    .ask-road-return-btn {
      grid-column: 1 / -1;
      padding: 10px;
      font-size: 14px;
      font-weight: 600;
      border: none;
      cursor: pointer;
      border-radius: 5px;
      text-align: center;
      background: var(--highlight-color);
      color: white;
      margin-top: 8px;
    }
    
    .red-text {
      color: var(--red-color);
    }
    
    .blue-text {
      color: var(--blue-color);
    }
    
    .gh-grid {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 0;
      margin: 0 auto;
      width: fit-content;
    }
    
    .gh-cell {
      width: 18px;
      height: 18px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-weight: bold;
      font-size: 12px;
      margin: 0;
      padding: 0;
    }
    
    .gh-positive {
      background-color: rgba(46, 204, 113, 0.2);
      color: var(--trend-positive);
    }
    
    .gh-negative {
      background-color: rgba(231, 76, 60, 0.2);
      color: var(--trend-negative);
    }
    
    .comprehensive-grid {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 0;
      margin: 0 auto;
      width: fit-content;
    }
    
    .comprehensive-cell {
      width: 22px;
      height: 18px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-weight: bold;
      font-size: 12px;
      margin: 0;
      padding: 0;
      position: relative;
    }
    
    .comprehensive-cell.with-number {
      font-size: 10px;
    }
    
    .comprehensive-cell span {
      display: inline-block;
      width: 16px;
      text-align: center;
    }
    
    .comprehensive-cell sub {
      font-size: 8px;
      position: relative;
      bottom: -2px;
    }
    
    .betting-system-container {
      width: 100%;
      max-width: 600px;
      margin-bottom: 15px;
      background: var(--table-bg);
      border-radius: 8px;
      padding: 10px;
      border: 1px solid var(--border-color);
    }
    
    .betting-title {
      text-align: center;
      font-size: 16px;
      color: var(--highlight-color);
      margin-bottom: 8px;
      font-weight: bold;
      font-family: 'Segoe UI', 'Microsoft JhengHei', sans-serif;
    }
    
    .betting-input-container {
      display: flex;
      flex-direction: column;
      gap: 8px;
      margin-bottom: 15px;
    }
    
    .betting-input {
      padding: 8px 12px;
      border-radius: 5px;
      border: 1px solid var(--border-color);
      background-color: var(--primary-color);
      color: var(--text-color);
      font-size: 14px;
    }
    
    .betting-input:focus {
      outline: none;
      border-color: var(--highlight-color);
    }
    
    .betting-grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 8px;
    }
    
    .betting-item {
      background-color: var(--primary-color);
      border-radius: 5px;
      padding: 8px;
      text-align: center;
      font-size: 12px;
      border: 1px solid var(--border-color);
      color: white;
    }
    
    .betting-item-header {
      background-color: var(--primary-color);
      color: var(--text-color);
      font-weight: 600;
    }
    
    .betting-item-content {
      display: flex;
      flex-direction: column;
      gap: 2px;
    }
    
    .betting-layer {
      font-weight: bold;
      color: white;
    }
    
    .betting-amount {
      font-size: 11px;
      color: white;
    }
    
    .betting-prompt {
      text-align: center;
      color: var(--highlight-color);
      font-size: 14px;
      margin: 15px 0;
      font-style: italic;
    }
    
    .hidden {
      display: none;
    }
    
    /* 後台管理系統樣式 */
    .admin-panel {
      display: none;
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: var(--primary-color);
      z-index: 10001;
      padding: 20px;
      overflow-y: auto;
    }
    
    .admin-header {
      text-align: center;
      margin-bottom: 20px;
      padding-bottom: 15px;
      border-bottom: 1px solid var(--border-color);
      display: flex;
      justify-content: space-between;
      align-items: center;
    }
    
    .admin-title {
      color: var(--highlight-color);
      font-size: 24px;
      margin-bottom: 10px;
    }
    
    .admin-tabs {
      display: flex;
      gap: 10px;
      margin-bottom: 20px;
      flex-wrap: wrap;
    }
    
    .admin-tab {
      padding: 10px 15px;
      background: var(--border-color);
      color: white;
      border: none;
      border-radius: 6px;
      cursor: pointer;
      font-size: 14px;
      flex: 1;
      min-width: 120px;
    }
    
    .admin-tab.active {
      background: var(--highlight-color);
    }
    
    .admin-controls {
      display: flex;
      gap: 10px;
      margin-bottom: 20px;
      flex-wrap: wrap;
    }
    
    .admin-btn {
      padding: 10px 15px;
      background: var(--blue-color);
      color: white;
      border: none;
      border-radius: 6px;
      cursor: pointer;
      font-size: 14px;
    }
    
    .admin-btn-danger {
      background: var(--red-color);
    }
    
    .admin-btn-success {
      background: var(--profit-positive);
    }
    
    .license-table {
      width: 100%;
      border-collapse: collapse;
      background: var(--secondary-color);
      border-radius: 8px;
      overflow: hidden;
      table-layout: fixed;
    }
    
    .license-table th,
    .license-table td {
      padding: 6px 4px;
      text-align: center;
      border-bottom: 1px solid var(--border-color);
      font-size: 11px;
      white-space: normal;
      line-height: 1.2;
    }
    
    .license-table th {
      background: var(--primary-color);
      color: var(--highlight-color);
      font-weight: 600;
      font-size: 12px;
      padding: 8px 4px;
    }
    
    /* 优化后台表格显示 - 新增样式 */
    .license-table th:nth-child(1),
    .license-table td:nth-child(1) {
      width: 12%;
    }
    
    .license-table th:nth-child(2),
    .license-table td:nth-child(2),
    .license-table th:nth-child(3),
    .license-table td:nth-child(3) {
      width: 22%;
    }
    
    .license-table th:nth-child(4),
    .license-table td:nth-child(4) {
      width: 8%;
    }
    
    .license-table th:nth-child(5),
    .license-table td:nth-child(5) {
      width: 12%;
    }
    
    .license-table th:nth-child(6),
    .license-table td:nth-child(6) {
      width: 24%;
    }
    
    .status-indicator {
      display: inline-block;
      width: 14px;
      height: 14px;
      border-radius: 50%;
      margin-right: 5px;
    }
    
    .status-online {
      background: var(--profit-positive);
      box-shadow: 0 0 5px var(--profit-positive);
    }
    
    .status-offline {
      background: #95a5a6;
    }
    
    .status-expired {
      background: var(--profit-negative);
    }
    
    .action-buttons {
      display: flex;
      gap: 8px;
      justify-content: center;
      align-items: center;
      flex-wrap: nowrap;
    }
    
    .action-btn {
      padding: 3px 6px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 10px;
    }
    
    .btn-kick {
      background: var(--red-color);
      color: white;
    }
    
    .ban-toggle {
      width: 16px;
      height: 16px;
      border-radius: 50%;
      border: none;
      cursor: pointer;
      background: #95a5a6;
    }
    
    .ban-toggle.active {
      background: var(--profit-positive);
      box-shadow: 0 0 5px var(--profit-positive);
    }
    
    .new-trial-form {
      background: var(--secondary-color);
      padding: 15px;
      border-radius: 8px;
      margin-bottom: 20px;
      display: none;
    }
    
    .form-group {
      margin-bottom: 10px;
    }
    
    .form-input {
      width: 100%;
      padding: 8px 12px;
      border-radius: 6px;
      border: 1px solid var(--border-color);
      background: var(--primary-color);
      color: var(--text-color);
    }
    
    /* 移除統計面板 */
    .stats-panel {
      display: none;
    }
  </style>
</head>
<body>
  <!-- 登录页面 -->
  <div class="login-container" id="loginContainer">
    <div class="login-box">
      <h1 class="login-title">三維量化分析1.0</h1>
      
      <!-- 用戶驗證碼輸入 -->
      <input type="text" id="licenseKey" class="login-input" placeholder="請輸入7位驗證碼" autocomplete="off" maxlength="7">
      
      <!-- 管理員密碼輸入 -->
      <input type="password" id="adminPassword" class="login-input" placeholder="管理員密碼" autocomplete="off">
      
      <button class="login-btn" id="loginBtn">登入系統</button>
      <div class="contact-info">請聯繫WeChat:nss9943索取付費資訊</div>
      <div id="loginMessage" class="login-message"></div>
    </div>
  </div>

  <!-- 後台管理系統 -->
  <div class="admin-panel" id="adminPanel">
    <div class="admin-header">
      <h1 class="admin-title">後台管理系統</h1>
      <button class="logout-btn" id="adminLogoutBtn">登出</button>
    </div>
    
    <!-- 分類標籤 -->
    <div class="admin-tabs">
      <button class="admin-tab active" data-tab="expired">已失效驗證碼</button>
      <button class="admin-tab" data-tab="active">未失效驗證碼</button>
      <button class="admin-tab" data-tab="trial">試用驗證碼</button>
    </div>
    
    <!-- 控制按鈕 -->
    <div class="admin-controls">
      <button class="admin-btn admin-btn-success" id="addTrialBtn">新增試用驗證碼</button>
      <button class="admin-btn" id="refreshBtn">刷新數據</button>
    </div>
    
    <!-- 新增試用驗證碼表單 -->
    <div class="new-trial-form" id="newTrialForm">
      <h3>新增試用驗證碼</h3>
      <div class="form-group">
        <input type="text" id="newTrialKey" class="form-input" placeholder="輸入7位驗證碼" maxlength="7">
      </div>
      <div class="admin-controls">
        <button class="admin-btn admin-btn-success" id="saveTrialBtn">保存</button>
        <button class="admin-btn" id="cancelTrialBtn">取消</button>
      </div>
    </div>
    
    <!-- 驗證碼列表 -->
    <table class="license-table">
      <thead>
        <tr>
          <th style="width: 12%">驗證碼</th>
          <th style="width: 22%">起始</th>
          <th style="width: 22%">到期</th>
          <th style="width: 8%">期限</th>
          <th style="width: 12%">狀態</th>
          <th style="width: 24%">操作</th>
        </tr>
      </thead>
      <tbody id="licenseTableBody">
        <tr>
          <td colspan="6" style="text-align: center; padding: 20px;">暫無數據</td>
        </tr>
      </tbody>
    </table>
  </div>

  <!-- 主系统内容 -->
  <div class="main-system" id="mainSystem">
    <div class="header">
      <h1>三維量化分析1.0</h1>
      <div class="header-controls">
        <div class="countdown-display" id="headerCountdown">00:00:00</div>
        <button class="logout-btn" id="userLogoutBtn">登出</button>
      </div>
    </div>
    
    <div class="modules-container">
      <!-- 模块1 -->
      <div class="module" id="module1">
        <div class="module-title">模块1</div>
        <div class="board-container">
          <div class="board" id="board1"></div>
          <div id="scrollTip1" class="scroll-tip"></div>
        </div>
        
        <div class="buttons-container">
          <div class="btn-group">
            <button class="btn btn-blue" data-module="1">蓝</button>
            <button class="btn btn-red" data-module="1">红</button>
          </div>
          <div class="btn-group">
            <button class="btn btn-reset" data-module="1">重置</button>
            <button class="btn btn-back" data-module="1">返回</button>
          </div>
        </div>
      </div>
      
      <!-- 模块2 -->
      <div class="module" id="module2">
        <div class="module-title">模块2</div>
        <div class="board-container">
          <div class="board" id="board2"></div>
          <div id="scrollTip2" class="scroll-tip"></div>
        </div>
        
        <div class="buttons-container">
          <div class="btn-group">
            <button class="btn btn-blue" data-module="2">蓝</button>
            <button class="btn btn-red" data-module="2">红</button>
          </div>
          <div class="btn-group">
            <button class="btn btn-reset" data-module="2">重置</button>
            <button class="btn btn-back" data-module="2">返回</button>
          </div>
        </div>
      </div>
      
      <!-- 模块3 -->
      <div class="module" id="module3">
        <div class="module-title">模块3</div>
        <div class="board-container">
          <div class="board" id="board3"></div>
          <div id="scrollTip3" class="scroll-tip"></div>
        </div>
        
        <div class="buttons-container">
          <div class="btn-group">
            <button class="btn btn-blue" data-module="3">蓝</button>
            <button class="btn btn-red" data-module="3">红</button>
          </div>
          <div class="btn-group">
            <button class="btn btn-reset" data-module="3">重置</button>
            <button class="btn btn-back" data-module="3">返回</button>
          </div>
        </div>
      </div>
    </div>

    <div class="prediction-table-container">
      <div class="card-title">量化走勢紀錄</div>
      
      <table class="prediction-table">
        <thead>
          <tr>
            <th>模塊1走勢</th>
            <th>模塊2走勢</th>
            <th>模塊3走勢</th>
            <th>綜合走勢</th>
          </tr>
        </thead>
        <tbody id="predictionTableBody">
          <tr>
            <td colspan="4" style="text-align: center; padding: 20px;">暂无数据</td>
          </tr>
        </tbody>
      </table>
      
      <!-- 组合问路按钮 -->
      <div class="ask-road-container">
        <div class="ask-road-title">组合问路</div>
        <button class="ask-road-btn" data-pattern="RRR">
          <span class="red-text">O</span><span class="red-text">O</span><span class="red-text">O</span>
        </button>
        <button class="ask-road-btn" data-pattern="RRB">
          <span class="red-text">O</span><span class="red-text">O</span><span class="blue-text">X</span>
        </button>
        <button class="ask-road-btn" data-pattern="RBB">
          <span class="red-text">O</span><span class="blue-text">X</span><span class="blue-text">X</span>
        </button>
        <button class="ask-road-btn" data-pattern="RBR">
          <span class="red-text">O</span><span class="blue-text">X</span><span class="red-text">O</span>
        </button>
        <button class="ask-road-btn" data-pattern="BBB">
          <span class="blue-text">X</span><span class="blue-text">X</span><span class="blue-text">X</span>
        </button>
        <button class="ask-road-btn" data-pattern="BBR">
          <span class="blue-text">X</span><span class="blue-text">X</span><span class="red-text">O</span>
        </button>
        <button class="ask-road-btn" data-pattern="BRR">
          <span class="blue-text">X</span><span class="red-text">O</span><span class="red-text">O</span>
        </button>
        <button class="ask-road-btn" data-pattern="BRB">
          <span class="blue-text">X</span><span class="red-text">O</span><span class="blue-text">X</span>
        </button>
        
        <button class="ask-road-return-btn" id="askRoadReturnBtn" disabled>问路返回</button>
      </div>
    </div>
    
    <!-- 层数打法区域 -->
    <div class="betting-system-container">
      <div class="betting-title">層數打法</div>
      
      <div class="betting-input-container">
        <input type="number" id="startingAmount" class="betting-input" placeholder="輸入起始金額" min="1">
      </div>
      
      <div id="bettingPrompt" class="betting-prompt">請輸入起始金額以顯示注碼層級</div>
      
      <div class="betting-grid hidden" id="bettingGrid">
        <!-- 注码将在这里动态生成 -->
        <div class="betting-item betting-item-header">層數</div>
        <div class="betting-item betting-item-header">第一口</div>
        <div class="betting-item betting-item-header">第二口</div>
      </div>
    </div>
    
    <div class="warning-text">⚠️ 此為演示系統，僅供學習研究使用</div>

    <div class="overlay" id="overlay">訊息</div>
  </div>

  <script>
    // 初始化 Supabase 客户端
    const SUPABASE_URL = 'https://hspypsdskcaoccafblqf.supabase.co';
    const SUPABASE_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImhzcHlwc2Rza2Nhb2NjYWZibHFmIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjAwODI4NTEsImV4cCI6MjA3NTY1ODg1MX0.q23mRe8lbUkAw-NpEdr_HxBKAWoLGA257Z3dFbwTgR8';
    const supabase = supabase.createClient(SUPABASE_URL, SUPABASE_KEY);

    // 增強版許可證系統
    class EnhancedLicenseSystem {
      constructor() {
        // 管理員密碼
        this.ADMIN_PASSWORD = "nianyuhsiangnss191919";
        
        // DOM 元素
        this.loginContainer = document.getElementById('loginContainer');
        this.mainSystem = document.getElementById('mainSystem');
        this.adminPanel = document.getElementById('adminPanel');
        this.licenseKeyInput = document.getElementById('licenseKey');
        this.adminPasswordInput = document.getElementById('adminPassword');
        this.loginBtn = document.getElementById('loginBtn');
        this.loginMessage = document.getElementById('loginMessage');
        this.countdownContainer = document.getElementById('countdownContainer');
        this.countdownText = document.getElementById('countdownText');
        this.headerCountdown = document.getElementById('headerCountdown');
        this.userLogoutBtn = document.getElementById('userLogoutBtn');
        this.adminLogoutBtn = document.getElementById('adminLogoutBtn');
        
        // 後台管理元素
        this.adminTabs = document.querySelectorAll('.admin-tab');
        this.addTrialBtn = document.getElementById('addTrialBtn');
        this.refreshBtn = document.getElementById('refreshBtn');
        this.newTrialForm = document.getElementById('newTrialForm');
        this.saveTrialBtn = document.getElementById('saveTrialBtn');
        this.cancelTrialBtn = document.getElementById('cancelTrialBtn');
        this.newTrialKeyInput = document.getElementById('newTrialKey');
        this.licenseTableBody = document.getElementById('licenseTableBody');
        
        this.countdownInterval = null;
        this.heartbeatInterval = null;
        this.remainingTime = 0;
        this.currentLicenseKey = null;
        this.currentTab = 'expired';
        
        this.init();
      }
      
      init() {
        // 先顯示登入頁面
        this.showLoginPage();
        
        // 綁定事件
        this.loginBtn.addEventListener('click', () => {
          this.validateLogin();
        });
        
        this.licenseKeyInput.addEventListener('keypress', (e) => {
          if (e.key === 'Enter') {
            this.validateLogin();
          }
        });
        
        this.adminPasswordInput.addEventListener('keypress', (e) => {
          if (e.key === 'Enter') {
            this.validateLogin();
          }
        });
        
        // 登出按鈕
        this.userLogoutBtn.addEventListener('click', () => {
          this.userLogout();
        });
        
        this.adminLogoutBtn.addEventListener('click', () => {
          this.adminLogout();
        });
        
        // 後台管理事件
        this.adminTabs.forEach(tab => {
          tab.addEventListener('click', () => {
            this.switchTab(tab.dataset.tab);
          });
        });
        
        this.addTrialBtn.addEventListener('click', () => {
          this.showNewTrialForm();
        });
        
        this.refreshBtn.addEventListener('click', () => {
          this.refreshAdminPanel();
        });
        
        this.saveTrialBtn.addEventListener('click', () => {
          this.saveNewTrial();
        });
        
        this.cancelTrialBtn.addEventListener('click', () => {
          this.hideNewTrialForm();
        });
        
        // 初始化後台數據
        this.initLicenseData();
      }
      
      async validateLogin() {
        const licenseKey = this.licenseKeyInput.value.trim();
        const adminPassword = this.adminPasswordInput.value.trim();
        
        // 檢查是否為管理員登入
        if (adminPassword === this.ADMIN_PASSWORD) {
          if (licenseKey) {
            this.showMessage('已使用管理員身份登入，忽略驗證碼輸入', 'success');
          }
          this.showAdminPanel();
          return;
        }
        
        // 檢查是否為用戶登入
        if (!licenseKey) {
          this.showMessage('請輸入驗證碼', 'error');
          return;
        }
        
        if (licenseKey.length !== 7) {
          this.showMessage('驗證碼必須為7位字符', 'error');
          return;
        }
        
        try {
          // 從 Supabase 檢查許可證
          const { data: license, error } = await supabase
            .from('licenses')
            .select('*')
            .eq('key', licenseKey)
            .single();
          
          if (error || !license) {
            this.showMessage('許可證無效或不存在', 'error');
            return;
          }
          
          if (license.banned) {
            this.showMessage('此許可證已被禁用', 'error');
            return;
          }
          
          const now = new Date();
          const expiryTime = new Date(license.expiry_time);
          
          if (license.expiry_time && now > expiryTime) {
            this.showMessage('許可證已過期', 'error');
            return;
          }
          
          // 更新最後活動時間
          await supabase
            .from('licenses')
            .update({ last_active: new Date().toISOString() })
            .eq('key', licenseKey);
          
          // 設置倒計時
          if (license.type === 'trial') {
            this.remainingTime = 60 * 60; // 1小時
          } else {
            // 計算剩餘時間（天數轉秒數）
            const remainingMs = expiryTime - now;
            this.remainingTime = Math.floor(remainingMs / 1000);
          }
          
          // 保存當前許可證
          this.currentLicenseKey = licenseKey;
          
          // 顯示主系統
          this.showMainSystem();
          this.startCountdown();
          this.startHeartbeat();
          
          if (license.type === 'trial') {
            this.showMessage('試用驗證成功！您有1小時使用時間', 'success');
          } else {
            this.showMessage(`驗證成功！許可證有效期至 ${expiryTime.toLocaleDateString()}`, 'success');
          }
        } catch (error) {
          console.error('驗證錯誤:', error);
          this.showMessage('系統錯誤，請稍後再試', 'error');
        }
      }
      
      async saveNewTrial() {
        const trialKey = this.newTrialKeyInput.value.trim();
        
        if (!trialKey || trialKey.length !== 7) {
          alert('請輸入有效的7位驗證碼');
          return;
        }
        
        try {
          // 檢查是否已存在
          const { data: existingLicense } = await supabase
            .from('licenses')
            .select('key')
            .eq('key', trialKey)
            .single();
          
          if (existingLicense) {
            alert('此驗證碼已存在');
            return;
          }
          
          // 添加試用許可證到 Supabase
          const { error } = await supabase
            .from('licenses')
            .insert([{
              key: trialKey,
              type: 'trial',
              days: 0,
              created_at: new Date().toISOString()
            }]);
          
          if (error) {
            alert('添加失敗: ' + error.message);
            return;
          }
          
          this.hideNewTrialForm();
          this.refreshAdminPanel();
          alert('試用驗證碼添加成功');
        } catch (error) {
          alert('添加失敗: ' + error.message);
        }
      }
      
      async refreshAdminPanel() {
        try {
          const { data: licenses, error } = await supabase
            .from('licenses')
            .select('*')
            .order('created_at', { ascending: false });
          
          if (error) {
            console.error('獲取許可證失敗:', error);
            return;
          }
          
          this.updateLicenseTable(licenses || []);
        } catch (error) {
          console.error('刷新數據失敗:', error);
        }
      }
      
      updateLicenseTable(licenses) {
        const tbody = this.licenseTableBody;
        tbody.innerHTML = '';
        
        // 根據當前標籤過濾數據
        let filteredLicenses = [];
        const now = new Date();
        
        switch (this.currentTab) {
          case 'expired':
            // 已失效許可證 - 只顯示正規許可證且已過期
            filteredLicenses = licenses.filter(l => 
              l.type === 'normal' && 
              l.expiry_time && 
              new Date(l.expiry_time) < now
            );
            break;
            
          case 'active':
            // 未失效許可證 - 只顯示正規許可證且未過期
            filteredLicenses = licenses.filter(l => 
              l.type === 'normal' && 
              (!l.expiry_time || new Date(l.expiry_time) >= now)
            );
            break;
            
          case 'trial':
            // 試用許可證 - 顯示所有試用許可證
            filteredLicenses = licenses.filter(l => l.type === 'trial');
            break;
        }
        
        if (filteredLicenses.length === 0) {
          tbody.innerHTML = '<tr><td colspan="6" style="text-align: center; padding: 20px;">暫無數據</td></tr>';
          return;
        }
        
        filteredLicenses.forEach(license => {
          const row = document.createElement('tr');
          
          // 驗證碼
          const keyCell = document.createElement('td');
          keyCell.textContent = license.key;
          row.appendChild(keyCell);
          
          // 起始時間
          const loginCell = document.createElement('td');
          if (license.login_time) {
            const date = new Date(license.login_time);
            const dateStr = `${date.getFullYear().toString().slice(-2)}/${(date.getMonth()+1).toString().padStart(2, '0')}/${date.getDate().toString().padStart(2, '0')}`;
            const timeStr = `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}`;
            loginCell.innerHTML = `<div style="font-size: 11px; line-height: 1.2;">${dateStr}<br>${timeStr}</div>`;
          } else {
            loginCell.textContent = '未使用';
            loginCell.style.fontSize = '11px';
          }
          row.appendChild(loginCell);
          
          // 到期時間
          const expiryCell = document.createElement('td');
          if (license.expiry_time) {
            const date = new Date(license.expiry_time);
            const dateStr = `${date.getFullYear().toString().slice(-2)}/${(date.getMonth()+1).toString().padStart(2, '0')}/${date.getDate().toString().padStart(2, '0')}`;
            const timeStr = `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}`;
            expiryCell.innerHTML = `<div style="font-size: 11px; line-height: 1.2;">${dateStr}<br>${timeStr}</div>`;
          } else {
            expiryCell.textContent = 'N/A';
            expiryCell.style.fontSize = '11px';
          }
          row.appendChild(expiryCell);
          
          // 期限
          const daysCell = document.createElement('td');
          if (license.type === 'trial') {
            daysCell.textContent = '1H';
          } else {
            daysCell.textContent = `${license.days}天`;
          }
          daysCell.style.fontSize = '11px';
          row.appendChild(daysCell);
          
          // 狀態
          const statusCell = document.createElement('td');
          statusCell.style.fontSize = '11px';
          const statusIndicator = document.createElement('span');
          statusIndicator.className = 'status-indicator';
          
          let statusText = '';
          const lastActive = license.last_active ? new Date(license.last_active) : null;
          const isOnline = lastActive && (Date.now() - lastActive.getTime()) < 300000; // 5分鐘內有活動
          
          if (license.banned) {
            statusIndicator.className += ' status-expired';
            statusText = '已禁用';
          } else if (license.expiry_time && new Date(license.expiry_time) < now) {
            statusIndicator.className += ' status-expired';
            statusText = '已過期';
          } else if (isOnline) {
            statusIndicator.className += ' status-online';
            statusText = '在線';
          } else {
            statusIndicator.className += ' status-offline';
            statusText = '離線';
          }
          
          statusCell.appendChild(statusIndicator);
          statusCell.appendChild(document.createTextNode(statusText));
          row.appendChild(statusCell);
          
          // 操作
          const actionCell = document.createElement('td');
          const actionButtons = document.createElement('div');
          actionButtons.className = 'action-buttons';
          
          // 踢出按鈕（只對未失效和試用許可證顯示）
          if (this.currentTab !== 'expired') {
            const kickBtn = document.createElement('button');
            kickBtn.className = 'action-btn btn-kick';
            kickBtn.textContent = '踢出';
            kickBtn.onclick = () => this.kickLicense(license.key);
            actionButtons.appendChild(kickBtn);
          }
          
          // 禁用開關
          const banBtn = document.createElement('button');
          banBtn.className = `ban-toggle ${license.banned ? 'active' : ''}`;
          banBtn.title = license.banned ? '啟用驗證碼' : '禁用驗證碼';
          banBtn.onclick = () => this.toggleBanLicense(license.key, !license.banned);
          actionButtons.appendChild(banBtn);
          
          actionCell.appendChild(actionButtons);
          row.appendChild(actionCell);
          
          tbody.appendChild(row);
        });
      }
      
      async kickLicense(licenseKey) {
        try {
          await supabase
            .from('licenses')
            .update({ last_active: null })
            .eq('key', licenseKey);
          
          this.refreshAdminPanel();
          alert(`已強制登出許可證: ${licenseKey}`);
        } catch (error) {
          alert('操作失敗: ' + error.message);
        }
      }
      
      async toggleBanLicense(licenseKey, banned) {
        try {
          await supabase
            .from('licenses')
            .update({ banned })
            .eq('key', licenseKey);
          
          this.refreshAdminPanel();
          const status = banned ? '禁用' : '啟用';
          alert(`許可證 ${licenseKey} 已${status}`);
        } catch (error) {
          alert('操作失敗: ' + error.message);
        }
      }
      
      startHeartbeat() {
        // 清除現有心跳
        if (this.heartbeatInterval) {
          clearInterval(this.heartbeatInterval);
        }
        
        // 每分鐘更新一次最後活動時間
        this.heartbeatInterval = setInterval(async () => {
          if (this.currentLicenseKey) {
            try {
              await supabase
                .from('licenses')
                .update({ last_active: new Date().toISOString() })
                .eq('key', this.currentLicenseKey);
            } catch (error) {
              console.error('心跳更新失敗:', error);
            }
          }
        }, 60000); // 每分鐘一次
      }
      
      // 其他方法保持不變...
      initLicenseData() {
        // 不再需要初始化本地存儲
      }
      
      showNewTrialForm() {
        this.newTrialForm.style.display = 'block';
        this.newTrialKeyInput.value = '';
      }
      
      hideNewTrialForm() {
        this.newTrialForm.style.display = 'none';
      }
      
      userLogout() {
        this.currentLicenseKey = null;
        this.showLoginPage();
        this.showMessage('已登出系統', 'success');
      }
      
      adminLogout() {
        this.showLoginPage();
        this.showMessage('管理員已登出', 'success');
      }
      
      showAdminPanel() {
        this.loginContainer.style.display = 'none';
        this.adminPanel.style.display = 'block';
        this.refreshAdminPanel();
      }
      
      showLoginPage() {
        this.adminPanel.style.display = 'none';
        this.mainSystem.style.display = 'none';
        this.loginContainer.style.display = 'flex';
        
        // 清除輸入框
        this.licenseKeyInput.value = '';
        this.adminPasswordInput.value = '';
        
        // 重置狀態
        this.currentLicenseKey = null;
        this.remainingTime = 0;
        
        // 清除計時器
        if (this.countdownInterval) {
          clearInterval(this.countdownInterval);
          this.countdownInterval = null;
        }
        if (this.heartbeatInterval) {
          clearInterval(this.heartbeatInterval);
          this.heartbeatInterval = null;
        }
      }
      
      switchTab(tabName) {
        this.currentTab = tabName;
        
        // 更新標籤狀態
        this.adminTabs.forEach(tab => {
          if (tab.dataset.tab === tabName) {
            tab.classList.add('active');
          } else {
            tab.classList.remove('active');
          }
        });
        
        this.refreshAdminPanel();
      }
      
      startCountdown() {
        if (this.countdownInterval) {
          clearInterval(this.countdownInterval);
        }
        
        this.updateCountdownDisplay();
        
        this.countdownInterval = setInterval(() => {
          this.remainingTime--;
          
          if (this.remainingTime <= 0) {
            this.remainingTime = 0;
            clearInterval(this.countdownInterval);
            this.userLogout();
          }
          
          this.updateCountdownDisplay();
        }, 1000);
      }
      
      updateCountdownDisplay() {
        if (!this.headerCountdown) return;
        
        if (this.remainingTime > 86400) {
          // 大於1天，顯示天數
          const days = Math.floor(this.remainingTime / (24 * 60 * 60));
          const hours = Math.floor((this.remainingTime % (24 * 60 * 60)) / (60 * 60));
          const timeString = `${days}天 ${hours.toString().padStart(2, '0')}:00:00`;
          const shortTimeString = `${days}天 ${hours}時`;
          
          this.headerCountdown.textContent = shortTimeString;
        } else {
          // 小於1天，顯示時分秒
          const hours = Math.floor(this.remainingTime / (60 * 60));
          const minutes = Math.floor((this.remainingTime % (60 * 60)) / 60);
          const seconds = this.remainingTime % 60;
          
          const timeString = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
          
          this.headerCountdown.textContent = timeString;
        }
      }
      
      showMainSystem() {
        this.loginContainer.style.display = 'none';
        this.mainSystem.style.display = 'block';
        
        // 初始化主系統
        if (typeof initMainSystem === 'function') {
          initMainSystem();
        }
      }
      
      showMessage(message, type) {
        this.loginMessage.textContent = message;
        this.loginMessage.className = `login-message login-${type}`;
        this.loginMessage.style.display = 'block';
        
        setTimeout(() => {
          this.loginMessage.style.display = 'none';
        }, 3000);
      }
      
      // 保持您原有的驗證碼解析方法（用於創建新許可證時）
      parseLicenseCode(code) {
        const letterMap = {
          'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 
          'F': 6, 'G': 7, 'H': 8, 'I': 9, 'Z': 0
        };
        
        const validLetters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'Z'];
        
        try {
          const char1 = code.charAt(0).toUpperCase();
          const char2 = code.charAt(1).toUpperCase();
          
          if (!validLetters.includes(char1) || !validLetters.includes(char2) || 
              char1 === 'Z' || char2 === 'Z') {
            return { valid: false, message: '第1-2位必須為A-I的英文字母' };
          }
          
          const num1 = letterMap[char1];
          const num2 = letterMap[char2];
          
          const sum = num1 + num2;
          const square = sum * sum;
          const expectedValue = square.toString().padStart(3, '0');
          
          const char3 = code.charAt(2).toUpperCase();
          
          if (!validLetters.includes(char3) || char3 === 'Z') {
            return { valid: false, message: '第3位必須為A-I的英文字母' };
          }
          
          const days = letterMap[char3];
          
          let actualValue = '';
          for (let i = 3; i <= 5; i++) {
            const char = code.charAt(i).toUpperCase();
            if (validLetters.includes(char)) {
              actualValue += letterMap[char].toString();
            } else if (/[0-9]/.test(char)) {
              actualValue += char;
            } else {
              return { valid: false, message: '第4-6位包含無效字符' };
            }
          }
          
          if (actualValue !== expectedValue) {
            return { valid: false, message: '驗證碼計算錯誤' };
          }
          
          const char7 = code.charAt(6).toUpperCase();
          let num7;
          
          if (validLetters.includes(char7)) {
            num7 = letterMap[char7];
          } else if (/[1-9]/.test(char7)) {
            num7 = parseInt(char7);
          } else {
            return { valid: false, message: '第7位必須為1-9或A-I' };
          }
          
          if (num7 + days !== 10) {
            return { valid: false, message: '第7位驗證失敗' };
          }
          
          return {
            valid: true,
            days: days
          };
        } catch (error) {
          return { valid: false, message: '驗證碼格式錯誤' };
        }
      }
    }

    // 啟動增強版系統
    document.addEventListener('DOMContentLoaded', () => {
      new EnhancedLicenseSystem();
    });

    // 您原有的所有其他代碼保持不變
    // 模塊類和主系統初始化代碼
    class Module {
      constructor(id) {
        this.id = id;
        this.history = [];
        this.previousStates = [];
        
        // 五层序列
        this.oxSequence = []; // 第一层：O/X
        this.abSequence = []; // 第二层：A/B
        this.cdSequence = []; // 第三层：C/D
        this.efSequence = []; // 第四层：E/F
        this.ghSequence = []; // 第五层：G/H
        
        this.predictionRecords = [];
        this.simulationRecords = [];
        this.tempAskRoadData = null;
      }

      // 初始化珠盘路
      initBoard() {
        const board = document.getElementById(`board${this.id}`);
        board.innerHTML = '';
        
        // 创建6列3行的空单元格
        for (let row = 0; row < 3; row++) {
          for (let col = 0; col < 6; col++) {
            const cell = document.createElement('div');
            cell.className = 'cell';
            board.appendChild(cell);
          }
        }
      }

      // 生成OX序列（第一层）
      generateOXSequence() {
        this.oxSequence = [];
        for (let i = 1; i < this.history.length; i++) {
          const prev = this.history[i-1];
          const curr = this.history[i];
          
          if (prev === curr) {
            this.oxSequence.push('O'); // 相同为O
          } else {
            this.oxSequence.push('X'); // 不同为X
          }
        }
      }
      
      // 生成AB序列（第二层）
      generateABSequence() {
        this.abSequence = [];
        for (let i = 1; i < this.oxSequence.length; i++) {
          const prev = this.oxSequence[i-1];
          const curr = this.oxSequence[i];
          
          if (prev === curr) {
            this.abSequence.push('A'); // 相同为A
          } else {
            this.abSequence.push('B'); // 不同为B
          }
        }
      }
      
      // 生成CD序列（第三层）
      generateCDSequence() {
        this.cdSequence = [];
        for (let i = 1; i < this.abSequence.length; i++) {
          const prev = this.abSequence[i-1];
          const curr = this.abSequence[i];
          
          if (prev === curr) {
            this.cdSequence.push('C'); // 相同为C
          } else {
            this.cdSequence.push('D'); // 不同为D
          }
        }
      }
      
      // 生成EF序列（第四层）
      generateEFSequence() {
        this.efSequence = [];
        for (let i = 1; i < this.cdSequence.length; i++) {
          const prev = this.cdSequence[i-1];
          const curr = this.cdSequence[i];
          
          if (prev === curr) {
            this.efSequence.push('E'); // 相同为E
          } else {
            this.efSequence.push('F'); // 不同为F
          }
        }
      }
      
      // 生成GH序列（第五层）
      generateGHSequence() {
        this.ghSequence = [];
        for (let i = 1; i < this.efSequence.length; i++) {
          const prev = this.efSequence[i-1];
          const curr = this.efSequence[i];
          
          if (prev === curr) {
            this.ghSequence.push('G'); // 相同为G
          } else {
            this.ghSequence.push('H'); // 不同为H
          }
        }
      }

      // 渲染遊戲板
      renderBoard() {
        const board = document.getElementById(`board${this.id}`);
        const scrollTip = document.getElementById(`scrollTip${this.id}`);
        board.innerHTML = '';
        
        const totalColumns = Math.ceil(this.history.length / 3);
        const startColumn = Math.max(0, totalColumns - 6);
        
        for (let row = 0; row < 3; row++) {
          for (let col = 0; col < 6; col++) {
            const columnIndex = startColumn + col;
            const index = columnIndex * 3 + row;
            
            const cell = document.createElement('div');
            cell.className = 'cell';
            
            if (index < this.history.length) {
              const circle = document.createElement('div');
              circle.className = `circle ${this.history[index] === 'R' ? 'red' : 'blue'}`;
              cell.appendChild(circle);
            }
            board.appendChild(cell);
          }
        }
        
        // 更新滾動提示
        if (totalColumns > 6) {
          scrollTip.textContent = `← 已隱藏 ${startColumn} 列`;
        } else {
          scrollTip.textContent = '';
        }
      }

      // 輸入結果
      enterResult(result) {
        // 保存狀態
        this.previousStates.push({
          history: [...this.history],
          oxSequence: [...this.oxSequence],
          abSequence: [...this.abSequence],
          cdSequence: [...this.cdSequence],
          efSequence: [...this.efSequence],
          ghSequence: [...this.ghSequence],
          predictionRecords: [...this.predictionRecords],
          simulationRecords: [...this.simulationRecords]
        });

        // 更新記錄
        this.history.push(result);

        // 更新序列
        this.generateOXSequence();
        this.generateABSequence();
        this.generateCDSequence();
        this.generateEFSequence();
        this.generateGHSequence();

        // 更新UI
        this.renderBoard();
        updatePredictionTable();

        showOverlay(`模块${this.id}已記錄：${result === 'R' ? '红' : '蓝'}`);
      }

      // 返回上一步
      undoLast() {
        if (this.previousStates.length === 0) return;
        
        const lastState = this.previousStates.pop();
        this.history = lastState.history;
        this.oxSequence = lastState.oxSequence;
        this.abSequence = lastState.abSequence;
        this.cdSequence = lastState.cdSequence;
        this.efSequence = lastState.efSequence;
        this.ghSequence = lastState.ghSequence;
        this.predictionRecords = lastState.predictionRecords;
        this.simulationRecords = lastState.simulationRecords;

        this.renderBoard();
        updatePredictionTable();

        showOverlay(`模块${this.id}已返回上一步`);
      }

      // 重置遊戲
      reset() {
        this.history = [];
        this.previousStates = [];
        this.oxSequence = [];
        this.abSequence = [];
        this.cdSequence = [];
        this.efSequence = [];
        this.ghSequence = [];
        this.predictionRecords = [];
        this.simulationRecords = [];
        this.tempAskRoadData = null;

        this.initBoard();
        updatePredictionTable();
        document.getElementById(`scrollTip${this.id}`).textContent = '';

        showOverlay(`模块${this.id}已重置系統`);
      }

      // 獲取延續性對照數據
      getContinuityData() {
        // 獲取GH序列（1/2格式）
        const ghData = this.ghSequence.map(s => s === 'G' ? '1' : '2');
        
        // 生成延續性對照序列
        const continuityData = [];
        
        // 序號0沒有前一個可比較，使用背景色（空白）
        if (ghData.length > 0) {
          continuityData.push(''); // 空字符串表示使用背景色
        }
        
        // 從序號1開始，比較當前與前一個位置
        for (let i = 1; i < ghData.length; i++) {
          const prev = ghData[i-1];
          const curr = ghData[i];
          
          if (prev === curr) {
            continuityData.push('+'); // 相同為+
          } else {
            continuityData.push('-'); // 不同為-
          }
        }
        
        return continuityData;
      }

      // 問路功能
      askRoad(result) {
        // 保存当前序列状态
        const savedSequences = {
          oxSequence: [...this.oxSequence],
          abSequence: [...this.abSequence],
          cdSequence: [...this.cdSequence],
          efSequence: [...this.efSequence],
          ghSequence: [...this.ghSequence]
        };
        
        // 临时添加结果到历史
        const tempHistory = [...this.history, result];
        
        // 临时生成序列
        const tempOX = [];
        for (let i = 1; i < tempHistory.length; i++) {
          const prev = tempHistory[i-1];
          const curr = tempHistory[i];
          tempOX.push(prev === curr ? 'O' : 'X');
        }
        
        const tempAB = [];
        for (let i = 1; i < tempOX.length; i++) {
          const prev = tempOX[i-1];
          const curr = tempOX[i];
          tempAB.push(prev === curr ? 'A' : 'B');
        }
        
        const tempCD = [];
        for (let i = 1; i < tempAB.length; i++) {
          const prev = tempAB[i-1];
          const curr = tempAB[i];
          tempCD.push(prev === curr ? 'C' : 'D');
        }
        
        const tempEF = [];
        for (let i = 1; i < tempCD.length; i++) {
          const prev = tempCD[i-1];
          const curr = tempCD[i];
          tempEF.push(prev === curr ? 'E' : 'F');
        }
        
        const tempGH = [];
        for (let i = 1; i < tempEF.length; i++) {
          const prev = tempEF[i-1];
          const curr = tempEF[i];
          tempGH.push(prev === curr ? 'G' : 'H');
        }
        
        // 生成臨時的延續性對照數據
        const tempContinuityData = [];
        const tempGHData = tempGH.map(s => s === 'G' ? '1' : '2');
        
        // 序號0沒有前一個可比較，使用背景色（空白）
        if (tempGHData.length > 0) {
          tempContinuityData.push(''); // 空字符串表示使用背景色
        }
        
        // 從序號1開始，比較當前與前一個位置
        for (let i = 1; i < tempGHData.length; i++) {
          const prev = tempGHData[i-1];
          const curr = tempGHData[i];
          
          if (prev === curr) {
            tempContinuityData.push('+'); // 相同為+
          } else {
            tempContinuityData.push('-'); // 不同為-
          }
        }
        
        // 保存临时数据
        this.tempAskRoadData = {
          continuityData: tempContinuityData
        };
        
        // 更新显示
        updatePredictionTable();
        
        showOverlay(`模块${this.id}已模拟：${result === 'R' ? '红' : '蓝'}`);
      }
      
      // 清除模拟记录
      clearSimulation() {
        this.tempAskRoadData = null;
        updatePredictionTable();
        showOverlay(`模块${this.id}已清除模拟记录`);
      }
      
      // 获取显示数据（优先使用模拟数据）
      getDisplayData() {
        if (this.tempAskRoadData) {
          return this.tempAskRoadData.continuityData;
        }
        return this.getContinuityData();
      }
    }

    // 創建三個模塊
    const module1 = new Module(1);
    const module2 = new Module(2);
    const module3 = new Module(3);
    const modules = [module1, module2, module3];
    
    // 全局状态 - 跟踪当前是否正在显示问路结果
    let isAskRoadActive = false;

    // 显示提示
    function showOverlay(message) {
      const overlay = document.getElementById('overlay');
      overlay.textContent = message;
      overlay.style.display = 'block';
      setTimeout(() => {
        overlay.style.display = 'none';
      }, 2000);
    }

    // 计算综合走势数据 - 修改后的逻辑
    function calculateComprehensiveTrend() {
      // 获取三个模块的延續性對照數據
      const module1Data = module1.getDisplayData();
      const module2Data = module2.getDisplayData();
      const module3Data = module3.getDisplayData();
      
      // 确定最大长度
      const maxLength = Math.max(module1Data.length, module2Data.length, module3Data.length);
      
      // 初始化综合走势数组
      const comprehensiveTrend = [];
      
      // 从序列0开始计算
      for (let i = 0; i < maxLength; i++) {
        // 根据您的要求，序号0和序号1保持空格
        if (i < 2) {
          comprehensiveTrend[i] = {symbol: '', count: 0};
          continue;
        }
        
        // 统计三个模块从前一个序号到当前序号的变化是否连贯
        let consistentCount = 0;
        let totalCount = 0;
        
        // 检查模块1
        if (i < module1Data.length && (i-1) < module1Data.length) {
          totalCount++;
          if (module1Data[i] === module1Data[i-1]) {
            consistentCount++;
          }
        }
        
        // 检查模块2
        if (i < module2Data.length && (i-1) < module2Data.length) {
          totalCount++;
          if (module2Data[i] === module2Data[i-1]) {
            consistentCount++;
          }
        }
        
        // 检查模块3
        if (i < module3Data.length && (i-1) < module3Data.length) {
          totalCount++;
          if (module3Data[i] === module3Data[i-1]) {
            consistentCount++;
          }
        }
        
        // 如果没有有效数据，保持空格
        if (totalCount === 0) {
          comprehensiveTrend[i] = {symbol: '', count: 0};
          continue;
        }
        
        // 根据连贯数量决定显示
        if (consistentCount >= 2) {
          // 多数为连贯，显示勾
          if (consistentCount === 3) {
            // 三个都是连贯，显示带数字的勾
            comprehensiveTrend[i] = {symbol: '✅', count: 3};
          } else {
            // 两个是连贯，显示普通勾
            comprehensiveTrend[i] = {symbol: '✅', count: 2};
          }
        } else {
          // 多数为不连贯，显示叉
          const inconsistentCount = totalCount - consistentCount;
          if (inconsistentCount === 3) {
            // 三个都是不连贯，显示带数字的叉
            comprehensiveTrend[i] = {symbol: '❌', count: 3};
          } else {
            // 两个是不连贯，显示普通叉
            comprehensiveTrend[i] = {symbol: '❌', count: 2};
          }
        }
      }
      
      return comprehensiveTrend;
    }

    // 更新預測紀錄表格
    function updatePredictionTable() {
      const tbody = document.getElementById('predictionTableBody');
      tbody.innerHTML = '';
      
      // 获取每个模块的延續性對照數據
      const module1Data = module1.getDisplayData();
      const module2Data = module2.getDisplayData();
      const module3Data = module3.getDisplayData();
      
      // 计算综合走势
      const comprehensiveTrend = calculateComprehensiveTrend();
      
      // 确定最大长度
      const maxLength = Math.max(
        module1Data.length, 
        module2Data.length, 
        module3Data.length,
        comprehensiveTrend.length
      );
      
      if (maxLength === 0) {
        tbody.innerHTML = '<tr><td colspan="4" style="text-align: center; padding: 20px;">暂无数据</td></tr>';
        return;
      }
      
      // 计算需要多少行（每行2个符号）
      const rowsNeeded = Math.ceil(maxLength / 2);
      
      // 创建行
      for (let rowIndex = 0; rowIndex < rowsNeeded; rowIndex++) {
        const row = document.createElement('tr');
        
        // 模块1走势 - 按照新的排序方式：奇數在第一列（左邊），偶數在第二列（右邊）
        const module1Cell = document.createElement('td');
        const module1Grid = document.createElement('div');
        module1Grid.className = 'gh-grid';
        
        // 左1（索引为奇数）
        if (rowIndex * 2 + 1 < module1Data.length) {
          const leftCell = document.createElement('div');
          const value = module1Data[rowIndex * 2 + 1];
          if (value === '') {
            // 空值，只使用背景色
            leftCell.className = 'gh-cell';
          } else {
            leftCell.className = `gh-cell ${value === '+' ? 'gh-positive' : 'gh-negative'}`;
            leftCell.textContent = value;
          }
          module1Grid.appendChild(leftCell);
        } else {
          const emptyCell = document.createElement('div');
          emptyCell.className = 'gh-cell';
          module1Grid.appendChild(emptyCell);
        }
        
        // 右1（索引为偶数）
        if (rowIndex * 2 < module1Data.length) {
          const rightCell = document.createElement('div');
          const value = module1Data[rowIndex * 2];
          if (value === '') {
            // 空值，只使用背景色
            rightCell.className = 'gh-cell';
          } else {
            rightCell.className = `gh-cell ${value === '+' ? 'gh-positive' : 'gh-negative'}`;
            rightCell.textContent = value;
          }
          module1Grid.appendChild(rightCell);
        } else {
          const emptyCell = document.createElement('div');
          emptyCell.className = 'gh-cell';
          module1Grid.appendChild(emptyCell);
        }
        
        module1Cell.appendChild(module1Grid);
        row.appendChild(module1Cell);
        
        // 模块2走势 - 按照新的排序方式：奇數在第一列（左邊），偶數在第二列（右邊）
        const module2Cell = document.createElement('td');
        const module2Grid = document.createElement('div');
        module2Grid.className = 'gh-grid';
        
        // 左1（索引为奇数）
        if (rowIndex * 2 + 1 < module2Data.length) {
          const leftCell = document.createElement('div');
          const value = module2Data[rowIndex * 2 + 1];
          if (value === '') {
            // 空值，只使用背景色
            leftCell.className = 'gh-cell';
          } else {
            leftCell.className = `gh-cell ${value === '+' ? 'gh-positive' : 'gh-negative'}`;
            leftCell.textContent = value;
          }
          module2Grid.appendChild(leftCell);
        } else {
          const emptyCell = document.createElement('div');
          emptyCell.className = 'gh-cell';
          module2Grid.appendChild(emptyCell);
        }
        
        // 右1（索引为偶数）
        if (rowIndex * 2 < module2Data.length) {
          const rightCell = document.createElement('div');
          const value = module2Data[rowIndex * 2];
          if (value === '') {
            // 空值，只使用背景色
            rightCell.className = 'gh-cell';
          } else {
            rightCell.className = `gh-cell ${value === '+' ? 'gh-positive' : 'gh-negative'}`;
            rightCell.textContent = value;
          }
          module2Grid.appendChild(rightCell);
        } else {
          const emptyCell = document.createElement('div');
          emptyCell.className = 'gh-cell';
          module2Grid.appendChild(emptyCell);
        }
        
        module2Cell.appendChild(module2Grid);
        row.appendChild(module2Cell);
        
        // 模块3走势 - 按照新的排序方式：奇數在第一列（左邊），偶數在第二列（右邊）
        const module3Cell = document.createElement('td');
        const module3Grid = document.createElement('div');
        module3Grid.className = 'gh-grid';
        
        // 左1（索引为奇数）
        if (rowIndex * 2 + 1 < module3Data.length) {
          const leftCell = document.createElement('div');
          const value = module3Data[rowIndex * 2 + 1];
          if (value === '') {
            // 空值，只使用背景色
            leftCell.className = 'gh-cell';
          } else {
            leftCell.className = `gh-cell ${value === '+' ? 'gh-positive' : 'gh-negative'}`;
            leftCell.textContent = value;
          }
          module3Grid.appendChild(leftCell);
        } else {
          const emptyCell = document.createElement('div');
          emptyCell.className = 'gh-cell';
          module3Grid.appendChild(emptyCell);
        }
        
        // 右1（索引为偶数）
        if (rowIndex * 2 < module3Data.length) {
          const rightCell = document.createElement('div');
          const value = module3Data[rowIndex * 2];
          if (value === '') {
            // 空值，只使用背景色
            rightCell.className = 'gh-cell';
          } else {
            rightCell.className = `gh-cell ${value === '+' ? 'gh-positive' : 'gh-negative'}`;
            rightCell.textContent = value;
          }
          module3Grid.appendChild(rightCell);
        } else {
          const emptyCell = document.createElement('div');
          emptyCell.className = 'gh-cell';
          module3Grid.appendChild(emptyCell);
        }
        
        module3Cell.appendChild(module3Grid);
        row.appendChild(module3Cell);
        
        // 综合走势
        const comprehensiveCell = document.createElement('td');
        const comprehensiveGrid = document.createElement('div');
        comprehensiveGrid.className = 'comprehensive-grid';
        
        // 左1（索引为奇数）
        if (rowIndex * 2 + 1 < comprehensiveTrend.length) {
          const leftCell = document.createElement('div');
          const trendData = comprehensiveTrend[rowIndex * 2 + 1];
          
          if (trendData.symbol === '') {
            // 空值，只使用背景色
            leftCell.className = 'comprehensive-cell';
          } else if (trendData.count === 3) {
            leftCell.className = 'comprehensive-cell with-number';
            leftCell.innerHTML = `<span>${trendData.symbol}<sub>${trendData.count}</sub></span>`;
          } else {
            leftCell.className = 'comprehensive-cell';
            leftCell.innerHTML = `<span>${trendData.symbol}</span>`;
          }
          comprehensiveGrid.appendChild(leftCell);
        } else {
          const emptyCell = document.createElement('div');
          emptyCell.className = 'comprehensive-cell';
          comprehensiveGrid.appendChild(emptyCell);
        }
        
        // 右1（索引为偶数）
        if (rowIndex * 2 < comprehensiveTrend.length) {
          const rightCell = document.createElement('div');
          const trendData = comprehensiveTrend[rowIndex * 2];
          
          if (trendData.symbol === '') {
            // 空值，只使用背景色
            rightCell.className = 'comprehensive-cell';
          } else if (trendData.count === 3) {
            rightCell.className = 'comprehensive-cell with-number';
            rightCell.innerHTML = `<span>${trendData.symbol}<sub>${trendData.count}</sub></span>`;
          } else {
            rightCell.className = 'comprehensive-cell';
            rightCell.innerHTML = `<span>${trendData.symbol}</span>`;
          }
          comprehensiveGrid.appendChild(rightCell);
        } else {
          const emptyCell = document.createElement('div');
          emptyCell.className = 'comprehensive-cell';
          comprehensiveGrid.appendChild(emptyCell);
        }
        
        comprehensiveCell.appendChild(comprehensiveGrid);
        row.appendChild(comprehensiveCell);
        
        tbody.appendChild(row);
      }
    }

    // 组合问路功能
    function combinedAskRoad(pattern) {
      // 如果已经有问路结果显示，先清除
      if (isAskRoadActive) {
        clearAskRoad();
      }
      
      // 为每个模块执行问路
      for (let i = 0; i < 3; i++) {
        const module = modules[i];
        const result = pattern[i] === 'R' ? 'R' : 'B';
        
        // 保存当前序列状态
        const savedSequences = {
          oxSequence: [...module.oxSequence],
          abSequence: [...module.abSequence],
          cdSequence: [...module.cdSequence],
          efSequence: [...module.efSequence],
          ghSequence: [...module.ghSequence]
        };
        
        // 临时添加结果到历史
        const tempHistory = [...module.history, result];
        
        // 临时生成序列
        const tempOX = [];
        for (let j = 1; j < tempHistory.length; j++) {
          const prev = tempHistory[j-1];
          const curr = tempHistory[j];
          tempOX.push(prev === curr ? 'O' : 'X');
        }
        
        const tempAB = [];
        for (let j = 1; j < tempOX.length; j++) {
          const prev = tempOX[j-1];
          const curr = tempOX[j];
          tempAB.push(prev === curr ? 'A' : 'B');
        }
        
        const tempCD = [];
        for (let j = 1; j < tempAB.length; j++) {
          const prev = tempAB[j-1];
          const curr = tempAB[j];
          tempCD.push(prev === curr ? 'C' : 'D');
        }
        
        const tempEF = [];
        for (let j = 1; j < tempCD.length; j++) {
          const prev = tempCD[j-1];
          const curr = tempCD[j];
          tempEF.push(prev === curr ? 'E' : 'F');
        }
        
        const tempGH = [];
        for (let j = 1; j < tempEF.length; j++) {
          const prev = tempEF[j-1];
          const curr = tempEF[j];
          tempGH.push(prev === curr ? 'G' : 'H');
        }
        
        // 生成臨時的延續性對照數據
        const tempContinuityData = [];
        const tempGHData = tempGH.map(s => s === 'G' ? '1' : '2');
        
        // 序號0沒有前一個可比較，使用背景色（空白）
        if (tempGHData.length > 0) {
          tempContinuityData.push(''); // 空字符串表示使用背景色
        }
        
        // 從序號1開始，比較當前與前一個位置
        for (let j = 1; j < tempGHData.length; j++) {
          const prev = tempGHData[j-1];
          const curr = tempGHData[j];
          
          if (prev === curr) {
            tempContinuityData.push('+'); // 相同為+
          } else {
            tempContinuityData.push('-'); // 不同為-
          }
        }
        
        // 保存临时数据
        module.tempAskRoadData = {
          continuityData: tempContinuityData
        };
      }
      
      // 设置状态为活动
      isAskRoadActive = true;
      
      // 禁用所有问路按钮，启用返回按钮
      document.querySelectorAll('.ask-road-btn').forEach(btn => {
        btn.disabled = true;
      });
      document.getElementById('askRoadReturnBtn').disabled = false;
      
      // 更新显示
      updatePredictionTable();
      
      // 显示提示
      const patternText = pattern.split('').map(char => char === 'R' ? '红' : '蓝').join('');
      showOverlay(`已模拟组合问路：${patternText}`);
    }

    // 清除问路结果
    function clearAskRoad() {
      // 清除所有模块的模拟数据
      modules.forEach(module => {
        module.tempAskRoadData = null;
      });
      
      // 设置状态为非活动
      isAskRoadActive = false;
      
      // 启用所有问路按钮，禁用返回按钮
      document.querySelectorAll('.ask-road-btn').forEach(btn => {
        btn.disabled = false;
      });
      document.getElementById('askRoadReturnBtn').disabled = true;
      
      // 更新显示
      updatePredictionTable();
      
      showOverlay('已清除模拟问路结果');
    }

    // 层数打法功能
    function initBettingSystem() {
      const startingAmountInput = document.getElementById('startingAmount');
      const bettingGrid = document.getElementById('bettingGrid');
      const bettingPrompt = document.getElementById('bettingPrompt');
      
      // 基础注码序列（100码对应）
      const baseBets = [105, 142, 192, 259, 350, 473, 639, 864, 1167, 1576, 2130, 2877, 3887, 5250, 7092];
      const baseTotal = 27003; // 基础总码数
      
      // 更新注码显示
      function updateBettingDisplay(amount) {
        if (!amount || amount <= 0) {
          // 如果没有输入或输入无效，隐藏注码网格，显示提示
          bettingGrid.classList.add('hidden');
          bettingPrompt.classList.remove('hidden');
          return;
        }
        
        // 隐藏提示，显示注码网格
          bettingPrompt.classList.add('hidden');
        bettingGrid.classList.remove('hidden');
        
        // 计算比例
        const ratio = amount / baseTotal;
        
        // 生成新的注码网格
        bettingGrid.innerHTML = '';
        
        // 添加表头
        const header1 = document.createElement('div');
        header1.className = 'betting-item betting-item-header';
        header1.textContent = '層數';
        bettingGrid.appendChild(header1);
        
        const header2 = document.createElement('div');
        header2.className = 'betting-item betting-item-header';
        header2.textContent = '第一口';
        bettingGrid.appendChild(header2);
        
        const header3 = document.createElement('div');
        header3.className = 'betting-item betting-item-header';
        header3.textContent = '第二口';
        bettingGrid.appendChild(header3);
        
        // 添加每层注码
        for (let i = 0; i < baseBets.length; i++) {
          const layer = i + 1;
          const firstBet = Math.round(baseBets[i] * ratio);
          const secondBet = firstBet * 2;
          
          // 层数
          const layerItem = document.createElement('div');
          layerItem.className = 'betting-item';
          layerItem.innerHTML = `<span class="betting-layer">${layer}</span>`;
          bettingGrid.appendChild(layerItem);
          
          // 第一口注码
          const firstBetItem = document.createElement('div');
          firstBetItem.className = 'betting-item';
          firstBetItem.innerHTML = `<span class="betting-amount">${firstBet}</span>`;
          bettingGrid.appendChild(firstBetItem);
          
          // 第二口注码
          const secondBetItem = document.createElement('div');
          secondBetItem.className = 'betting-item';
          secondBetItem.innerHTML = `<span class="betting-amount">${secondBet}</span>`;
          bettingGrid.appendChild(secondBetItem);
        }
      }
      
      // 监听输入变化
      startingAmountInput.addEventListener('input', function() {
        const amount = parseInt(this.value);
        updateBettingDisplay(amount);
      });
      
      // 初始状态隐藏注码网格，显示提示
      bettingGrid.classList.add('hidden');
      bettingPrompt.classList.remove('hidden');
    }

    // 初始化事件監聽
    function initEventListeners() {
      // 藍按鈕
      document.querySelectorAll('.btn-blue').forEach(btn => {
        btn.addEventListener('click', (e) => {
          const moduleId = parseInt(e.target.dataset.module);
          modules[moduleId - 1].enterResult('B');
        });
      });
      
      // 紅按鈕
      document.querySelectorAll('.btn-red').forEach(btn => {
        btn.addEventListener('click', (e) => {
          const moduleId = parseInt(e.target.dataset.module);
          modules[moduleId - 1].enterResult('R');
        });
      });
      
      // 重置按鈕
      document.querySelectorAll('.btn-reset').forEach(btn => {
        btn.addEventListener('click', (e) => {
          const moduleId = parseInt(e.target.dataset.module);
          modules[moduleId - 1].reset();
        });
      });
      
      // 返回按鈕
      document.querySelectorAll('.btn-back').forEach(btn => {
        btn.addEventListener('click', (e) => {
          const moduleId = parseInt(e.target.dataset.module);
          modules[moduleId - 1].undoLast();
        });
      });
      
      // 组合问路按钮 - 使用事件委托确保可靠的事件处理
      document.querySelector('.ask-road-container').addEventListener('click', (e) => {
        const button = e.target.closest('.ask-road-btn');
        if (button && !button.disabled) {
          const pattern = button.dataset.pattern;
          combinedAskRoad(pattern);
        }
        
        // 检查是否是返回按钮
        if (e.target.id === 'askRoadReturnBtn' && !e.target.disabled) {
          clearAskRoad();
        }
      });
    }

    // 初始化主系统
    function initMainSystem() {
      // 初始化珠盘路
      modules.forEach(module => module.initBoard());
      
      initEventListeners();u
      updatePredictionTable();
      initBettingSystem();
    }
  </script>
</body>
</html>